package com.hitqz.robot.biz.flow.component.agv;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hitqz.robot.api.common.entity.MapAreaAction;
import com.hitqz.robot.biz.flow.util.LiteFlowUtil;
import com.hitqz.robot.biz.service.MapAreaActionService;
import com.hitqz.robot.biz.service.RobotMapPosService;
import com.hitqz.robot.biz.service.RobotService;
import com.hitqz.robot.driver.model.IRobotPosDto;
import com.hitqz.robot.driver.parent.RobotDriverService;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.DataOutputStream;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * @author xupkun
 * @date 2024/12/21
 */
@Slf4j
@LiteflowComponent(value = "OpenAndCloseGate", name = "[轮对/轮轴]打开道闸门")
@RequiredArgsConstructor
public class OpenAndCloseGate extends NodeComponent {

    private final RobotMapPosService robotMapPosService;

    private final RobotService robotService;

    private final RobotDriverService robotDriverService;

    private final MapAreaActionService mapAreaActionService;


    public static final ThreadPoolExecutor networkExecutor = new ThreadPoolExecutor(
            5,               // 核心线程数
            10,              // 最大线程数
            60L,             // 非核心线程存活时间
            TimeUnit.SECONDS, // 时间单位
            new LinkedBlockingQueue<>(50),  // 阻塞队列
            Executors.defaultThreadFactory(), // 默认的线程工厂
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略：提交任务的线程执行任务
    );
    @Override
    public void process() throws Exception {
        log.info("Processing OpenAndClose");
        LiteFlowUtil.checkInterruptFlag();
        //networkExecutor.submit(() -> {
        //    try {
        //        FlowContextDto dto = this.getRequestData();
        //        TicketsTask task = dto.getTicketsTask();
        //        log.info("开关门任务数据 {}", task.getParseOrderParams());
        //
        //        FlowPatrolPreAndEndTicketsDto ticketsDto = JSONObject.parseObject(
        //                dto.getTicketsTask().getParseOrderParams(),
        //                FlowPatrolPreAndEndTicketsDto.class
        //        );
        //
        //        String sourceName = Optional.ofNullable(ticketsDto.getModalData().get("sourcePosName"))
        //                .orElse(ticketsDto.getModalData().get("sourcePosCode")).toString();
        //        String targetPosName = Optional.ofNullable(ticketsDto.getModalData().get("targetPosName"))
        //                .orElse(ticketsDto.getModalData().get("targetPosCode")).toString();
        //        if (isSourcePosition(sourceName)) {
        //            handlePosition("LM3", "LM10");
        //        } else if (isTargetPosition(sourceName, targetPosName)) {
        //            handlePosition("LM31", "LM212");
        //        }
        //        log.info("流程结束");
        //    } catch (Exception e) {
        //        log.error("处 理过程中发生异常: ", e);
        //        throw new RuntimeException("处理过程中发生异常", e);
        //    }
        //});
    }

    private boolean isSourcePosition(String sourceName) {
        return "911007".equals(sourceName) || "911008".equals(sourceName);
    }

    private boolean isTargetPosition(String sourceName,String targetPosName) {
        return (!sourceName.equals("911006")) && targetPosName.contains("911012");
    }

    private void handlePosition(String station1, String station2) {
        int maxRetries = 500;
        for (int i = 0; i < maxRetries; i++) {
            IRobotPosDto iRobotPosDto = robotDriverService.getWebPos();
            if (station1.equals(iRobotPosDto.getLastStation())) {
                executeOpenClose(station2, station1);
                return;
            } else if (station2.equals(iRobotPosDto.getLastStation())) {
                executeOpenClose(station1, station2);
                return;
            }
            try {
                Thread.sleep(1000); // 等待1秒后重试
            } catch (InterruptedException e) {
                log.warn("等待过程中被中断", e);
            }
        }
        log.error("达到最大重试次数，未找到目标站点");
    }

    private void executeOpenClose(String targetStation1, String targetStation2) {
        networkExecutor.submit(() -> {
            try {
                open();
                waitForTargetPos(targetStation1);
                close();
            } catch (Exception e) {
                log.error("执行开关门过程中发生异常: ", e);
                throw new RuntimeException("执行开关门过程中发生异常", e);
            }
        });
    }


    private void open() {
        try {
            MapAreaAction mapAreaAction = mapAreaActionService.getOne(Wrappers.<MapAreaAction>lambdaQuery().eq(MapAreaAction::getActionId, 3));
            if (mapAreaAction == null) {
                return;
            }
            String mapAreaActionParams = mapAreaAction.getParams();
            for (String ip : mapAreaActionParams.split(",")) {
                log.info("ip:" + ip);
                CompletableFuture.runAsync(()-> {
                    byte[] close1 = new byte[] {
                            (byte) 0xFE, 0x05, 0x00,0x00, (byte) 0x00, 0x00, (byte) 0xD9, (byte) 0xC5
                    };
                    byte[] open2 = new byte[] {
                            (byte)0xFE, 0x05, 0x00, 0x01,  (byte)0xFF, 0x00, (byte) 0xC9, (byte) 0xF5
                    };
                    byte[] open3 = new byte[] {
                            (byte) 0xFE, 0x05, 0x00, 0x02, (byte) 0xFF, 0x00, 0x39, (byte) 0xF5
                    };

                    byte[] open4 = new byte[] {
                            (byte) 0xFE, 0x05, 0x00, 0x03, (byte) 0xFF, 0x00, 0x68, (byte) 0x35
                    };

                    byte[] close2 = new byte[] {
                            (byte) 0xFE, 0x05, 0x00 , 0x01 , 0x00 , 0x00 , (byte) 0x88, 0x05
                    };

                    byte[] close3 = new byte[] {
                            (byte) 0xFE, 0x05 , 0x00 , 0x02 , 0x00 , 0x00 , 0x78 , 0x05
                    };
                    byte[] close4 = new byte[] {
                            (byte) 0xFE, 0x05 , 0x00 , 0x03 , 0x00 , 0x00 , 0x29 , (byte) 0xC5
                    };
                    send(ip, open3);
                    send(ip, open4);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    send(ip, close1);
                    send(ip, open2);
                    //try {
                    //    TimeUnit.MILLISECONDS.sleep(1000);
                    //} catch (InterruptedException e) {
                    //    throw new RuntimeException(e);
                    //}
                    //send(ip, close2);
                });
            }
        }catch (Exception e) {
            log.error("道闸控制异常", e);
        }

    }

    private void waitForTargetPos(String target) throws Exception {
        while (true) {
            IRobotPosDto iRobotPosDto =  robotDriverService.getWebPos();
            if (target.equals(iRobotPosDto.getLastStation())) {
                log.info("完成的站点: " + iRobotPosDto.getLastStation());
                break;
            }
            LiteFlowUtil.checkInterruptFlag();
        }


    }

    private void close() {
        try {
            MapAreaAction mapAreaAction = mapAreaActionService.getOne(Wrappers.<MapAreaAction>lambdaQuery().eq(MapAreaAction::getActionId, 3));
            if (mapAreaAction == null) {
                return;
            }
            String mapAreaActionParams = mapAreaAction.getParams();
            for (String ip : mapAreaActionParams.split(",")) {
                log.info("ip:" + ip);
                CompletableFuture.runAsync(()-> {
                    byte[] close2 = new byte[]{
                            (byte) 0xFE, 0x05, 0x00, 0x01, 0x00, 0x00, (byte) 0x88, 0x05
                    };
                    byte[] close3 = new byte[]{
                            (byte) 0xFE, 0x05, 0x00, 0x02, 0x00, 0x00, 0x78, 0x05
                    };
                    byte[] close4 = new byte[]{
                            (byte) 0xFE, 0x05, 0x00, 0x03, 0x00, 0x00, 0x29, (byte) 0xC5
                    };
                    byte[] open1 = new byte[]{
                            (byte) 0xFE, 0x05, 0x00, 0x00, (byte) 0xFF, 0x00, (byte) 0x98, 0x35
                    };
                    byte[] close1 = new byte[]{
                            (byte) 0xFE, 0x05, 0x00, 0x00, (byte) 0x00, 0x00, (byte) 0xD9, (byte) 0xC5
                    };
                    send(ip, close2);
                    send(ip, open1);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    send(ip, close3);
                    send(ip, close4);
                    //try {
                    //    Thread.sleep(1000);
                    //} catch (InterruptedException e) {
                    //    throw new RuntimeException(e);
                    //}
                    //send(ip, close1);
                });

            }
        }catch (Exception e) {
            log.error("道闸控制异常", e);
        }
    }


    public void send(String ip, byte[] data) {
        try {
            int port = 10000;
            Socket socket = new Socket(ip, port);
            socket.setSoTimeout(60000);
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            out.write(data);
            out.close();
            socket.close();
        } catch (Exception e) {

        }
    }
}
